package com.dom.stor.dao.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.dom.common.constants.ConstantError;
import com.dom.common.exception.ServiceException;
import com.dom.stor.dao.entity.TsStockInDetailFlow;
import com.dom.stor.dao.entity.TsStorGoodsInfo;
import com.dom.stor.dao.mapper.TsStorGoodsInfoMapper;
import com.dom.stor.dao.service.ITsStorGoodsInfoService;
import com.xiaoleilu.hutool.util.ObjectUtil;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * B_库存商品表 服务实现类
 * </p>
 *
 * @author xllei
 * @since 2019-01-01
 */
@Service
public class TsStorGoodsInfoServiceImpl extends ServiceImpl<TsStorGoodsInfoMapper, TsStorGoodsInfo> implements ITsStorGoodsInfoService {
    @Override
    public boolean addStorInitGoods(int memCode, Integer storId, Integer goodCode) {
        TsStorGoodsInfo storGoodsInfo = new TsStorGoodsInfo();
        storGoodsInfo.setMemCode(memCode);
        storGoodsInfo.setStorId(storId);
        storGoodsInfo.setGoodCode(goodCode);

        return this.insert(storGoodsInfo);
    }

    @Override
    public boolean addStorage(int memCode, Integer storId, Integer goodCode, BigDecimal amount) {
        Wrapper<TsStorGoodsInfo> wrapper = buildWhere(memCode, storId, goodCode);

        TsStorGoodsInfo entity = this.selectOne(wrapper);
        if (ObjectUtil.isNull(entity)) {
            throw new ServiceException(ConstantError.DATAERROR);
        }

        //计算库存总数、可用、可提/出库数量
        entity.setCurrAmt(entity.getCurrAmt().add(amount));
        entity.setUsbAmt(entity.getUsbAmt().add(amount));
        entity.setUsboutAmt(entity.getUsboutAmt().add(amount));

        return this.updateById(entity);
    }

    @Override
    public boolean addStorage(int memCode, Integer storId, List<TsStockInDetailFlow> stockInDetailFlows) {
        Map<Integer, BigDecimal> sumMap = new HashMap<>();
        Map<Integer, List<TsStockInDetailFlow>> groupMap = stockInDetailFlows.stream().collect(Collectors.groupingBy(TsStockInDetailFlow::getGoodCode));
        Iterator<Map.Entry<Integer, List<TsStockInDetailFlow>>> iterator = groupMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry entry = iterator.next();
            List<TsStockInDetailFlow> flowList = (List<TsStockInDetailFlow>) entry.getValue();

            BigDecimal sum = BigDecimal.ZERO;
            flowList.forEach(stockInDetailFlow -> {
                sum.add(stockInDetailFlow.getAmount());
            });
            sumMap.put((Integer) entry.getKey(), sum);

            Wrapper<TsStorGoodsInfo> wrapper = new EntityWrapper<>();
            wrapper.eq("stor_id", storId)
                    .and().eq("good_code", (Integer) entry.getKey());
            TsStorGoodsInfo stockInFlow = this.selectOne(wrapper);

            //增加库存、可用库存、剩余库存
            stockInFlow.setUsbAmt(stockInFlow.getUsbAmt().add(sum));
            stockInFlow.setUsboutAmt(stockInFlow.getUsboutAmt().add(sum));
            stockInFlow.setInAmt(stockInFlow.getInAmt().add(sum));
            this.updateById(stockInFlow);
        }

        return true;
    }

    @Override
    public boolean subStorage(int memCode, Integer storId, Integer goodCode, BigDecimal amount) {
        Wrapper<TsStorGoodsInfo> wrapper = buildWhere(memCode, storId, goodCode);

        TsStorGoodsInfo entity = this.selectOne(wrapper);
        if (ObjectUtil.isNull(entity)) {
            throw new ServiceException(ConstantError.DATAERROR);
        }

        //计算库存总数、可用、可提/出库数量
        entity.setCurrAmt(entity.getCurrAmt().subtract(amount));
        entity.setUsbAmt(entity.getUsbAmt().subtract(amount));
        entity.setUsboutAmt(entity.getUsboutAmt().subtract(amount));

        return this.updateById(entity);
    }

    @Override
    public boolean freezeStorage(int memCode, Integer storId, Integer goodCode, BigDecimal amount) {
        Wrapper<TsStorGoodsInfo> wrapper = buildWhere(memCode, storId, goodCode);

        TsStorGoodsInfo entity = this.selectOne(wrapper);
        if (ObjectUtil.isNull(entity)) {
            throw new ServiceException(ConstantError.DATAERROR);
        }

        entity.setUsbAmt(entity.getUsbAmt().subtract(amount));
        entity.setUsboutAmt(entity.getUsboutAmt().subtract(amount));
        return this.updateById(entity);
    }

    @Override
    public boolean unfreezeStorage(int memCode, Integer storId, Integer goodCode, BigDecimal amount) {
        Wrapper<TsStorGoodsInfo> wrapper = buildWhere(memCode, storId, goodCode);

        TsStorGoodsInfo entity = this.selectOne(wrapper);
        if (ObjectUtil.isNull(entity)) {
            throw new ServiceException(ConstantError.DATAERROR);
        }

        entity.setUsbAmt(entity.getUsbAmt().add(amount));
        entity.setUsboutAmt(entity.getUsboutAmt().add(amount));
        return this.updateById(entity);
    }

    private Wrapper<TsStorGoodsInfo> buildWhere(int memCode, Integer storId, Integer goodCode) {
        Wrapper<TsStorGoodsInfo> wrapper = new EntityWrapper<>();
        return wrapper.eq("mem_code", memCode)
                .eq("stor_id", storId)
                .and().eq("good_code", goodCode);
    }
}
